'''
Created on 03/09/2013

@author: loski07@gmail.com
'''
from controller.songManager import SongManager
from model.models import *
import os
import shutil
import tempfile
import unittest

class Test(unittest.TestCase):

    def setUp(self):
        self.tempdir = tempfile.mkdtemp()
        self.ordered_tree = Tree(self.tempdir)
        print 'Using temporary folder ' + self.tempdir
        
        for i in range(9):
            f = tempfile.NamedTemporaryFile('w+b', -1, '.mp3', str(i) + '-', self.tempdir, False)
            self.ordered_tree.add_song(Song(os.path.basename(f.name), self.tempdir))
            
        for i in range(3):
            aux = tempfile.mkdtemp("", "", self.tempdir)
            subtree_ord = Tree(aux)
            self.ordered_tree.add_subdir(subtree_ord)
            
            for j in range(8):
                f2 = tempfile.NamedTemporaryFile('w+b', -1, '.mp3', str(j) + '-', aux, False)
                subtree_ord.add_song(Song(os.path.basename(f2.name), aux))
    
    def tearDown(self):
        print 'Cleaning temporary folder ' + self.tempdir
        shutil.rmtree(self.tempdir)
        
    def _print_tree(self, tree, level=0):
        tab = ''.join(' ' for i in range(2 * level)) 
        print tab + '->' + tree.root_folder_name
        
        print tab + '|'
        for song in tree.songs:
            print tab + '|-' + song.filename
        
        print tab + '|'
        for subtree in tree.subdirs:
            self._print_tree(subtree, level + 1)
            
            
    def _similar(self, t1, t2):
        similar = True
        similar = similar and len(t1.songs) == len(t2.songs)
        similar = similar and len(t1.subdirs) == len(t2.subdirs)
        if not similar:
            return False, 'The length of the folder <{0}> is <Songs: {1}; Dirs: {2}> and does not match the expected <Songs: {3}; Dirs: {4}>'.format(t1.root_folder_name, len(t1.songs), len(t1.subdirs), len(t2.songs), len(t2.subdirs)) 
        
        for song in t1.songs:
            similar = similar and self._song_in(song, t2.songs)
            if not similar:
                return False, 'The song <{0}> from the folder <{1}> is not in <{2}>'.format(song.filename, t1.root_folder_name, self._cast_list_of_songs(t2.songs))

        i = 0
        for subtree in t1.subdirs:
            aux, problem = self._similar(subtree, t2.subdirs[i])
            if not similar and aux:
                return False, problem
            
        return similar, None

    def _equals(self, t1, t2):
        equals = True
        i = 0
        
        equals = equals and len(t1.songs) == len(t2.songs)
        equals = equals and len(t1.subdirs) == len(t2.subdirs)
        if not equals:
            return False, 'The length of the folder <{0}> is <Songs: {1}; Dirs: {2}> and does not match the expected <Songs: {3}; Dirs: {4}>'.format(t1.root_folder_name, len(t1.songs), len(t1.subdirs), len(t2.songs), len(t2.subdirs)) 
        
        for song in t1.songs:
            equals = equals and self._song_equals(t2.songs[i], song)
            if not equals:
                return False, 'The song <{0}> from the folder <{1}> does not match with the expected <{2}>'.format(song.filename, t1.root_folder_name, t2.songs[i].filename)
            i += 1
        
        i = 0
        for subtree in t1.subdirs:
            aux, problem = self._equals(subtree, t2.subdirs[i])
            if not equals and aux:
                return False, problem
            i += 1

        return equals, None
    
    def _song_equals(self, s1, s2):        
        return s1.filename == s2.filename

    def _song_in(self, s, l):
        for song_aux in l:
            if self._song_equals(s, song_aux):
                return True
        return False
            
    
    def _cast_list_of_songs(self, l):
        l2 = []
        for song in l:
            l2.append(song.filename)
        return l2
            
    def _assertion_tree_equals(self, t1, t2, comp_function):
        equals, problem = comp_function(t1, t2)
#         if not equals:
#             print 'obtained'
#             self._print_tree(t1)
#             print 'template:'
#             self._print_tree(t2)
        self.assertTrue(equals, problem)

    def testGetFolder(self):
        """
        Test method to check the procedure to get folder.
        """
        sm = SongManager()
        t = sm.get_folder(self.tempdir)
        
        self._assertion_tree_equals(t, self.ordered_tree, self._similar)
        
    def testSortTree(self):
        """
        Test method to check the procedure to sort the folder gotten.
        """
        sm = SongManager()
        t = sm.get_folder(self.tempdir)
        sm.sort_tree_alpha(t)
        
        self._assertion_tree_equals(t, self.ordered_tree, self._equals)

if __name__ == "__main__":
    # import sys;sys.argv = ['', 'Test.testName']
    unittest.main()
